Entrada Salida en sistemas operativos - IO Buffering - DriversBoot Process
Funciones
- Lograr eficiencia en el uso de los dispositivos de IO -> suelen ser el cuello de botella de los sistemas
- Generalidad -> manipular distintos dispositivos de igual manera
- Planificación de E/S
- Control de la E/S
- Logical IO -> Manipular dispositivo como un recurso lógico con operaciones básicas
- Interfaz con usuario
- Interfaz con otros dispositivos
- Buffering
IO Buffering
Cuando nos referimos a buffer, nos referimos a un lugar de almacenamiento temporal con información que será almacenada luego en otro lugar. Por lo general usamos buffers si ambos partícipes de la comunicación tienen distintas velocidades, en donde la comunicación no es sincrónica, sino que es asincrónica; y por otra parte, como unidad de transferencia entre ambas partes.
Hay un problema que vimos anteriormente en la página 82 cuando vimos memoria, que se solucionaba con el lockeo de páginas, pero lo que vemos en esa solución es que es bastante ineficiente si pensamos más allá que el lockeo de solo una página. Lo que hace el sistema operativo para solucionar este problema es generar un espacio de memoria dentro del espacio de memoria del sistema operativo con el fin de generar estos buffers para que se pueda hacer la entrada/salida. Por ejemplo, cuando me voy a traer algo de disco, puedo estar escribiendo en un buffer del sistema operativo, no necesito lockear ninguna página, y recién cuando esté la entrada/salida ahí se copia al espacio de direcciones del proceso.
En la imagen de abajo a la derecha podemos ver una serie de estrategias para implementar lo que vimos recientemente.
DriversBoot Process
¿Cómo es que nosotros cuando encendemos la PC empieza a correr el sistema operativo de la misma? Si el disco rígido donde probablemente se almacena el SO es solo un medio de almacenamiento secundario. Primero tiene que empezar algo antes para a posteriori ir a disco, y ese algo es la BIOS (Basic Input Output System), que es un sistema básico para manejar los dispositivos de entrada/salida, y que por lo general se almacena en una memoria ROM. La BIOS interpreta de donde se puede cargar el SO.
Un dispositivo puede ser booteable, y hasta puede tener distintas particiones booteables también. El MBR da la información básica para poder entender que hay en ese dispositivo, que particiones hay, si son booteables o no, etc. Una vez entendido esto, el MBR da paso a la carga del sistema operativo de ese dispositivo/partición, con el boot loader, el cual ya sí daría
N-STEP-SCAN
implementa más colas de atención con el fin de respetar más esa “justicia” entre los pedidos. Las colas de atención se van a ir ejecutando respetando el orden de llegada de c/u.
Hay que darle mucha importancia al número máximo de pedidos de cada cola, si nosotros le damos un número muy alto, al fin y al cabo funcionará como SCAN, o FSCAN, y si le damos un tamaño muy bajo como por ejemplo 1 solo pedido por cola, funcionará como un FIFO muy poco performante.
RAID
El objetivo de RAID es poder tener varios discos y poder interpretarlos como si fuese un único disco lógico para nosotros, con el fin de optimizar ciertos accesos (lectura, escritura), y para darles redundancia (tener cierta información extra que me permita recuperar el dato por si tiene un problema el dato original, como pasaba en la FAT con la copia, por ejemplo).
En RAID van a haber 2 métricas que podemos optimizar, no siempre vamos a poder optimizar todo:
RAID se va a basar en dividir a todo el contenido del disco lógico en franjas y poder distribuirlas entre varios discos. Ahora, si nuestra unidad de corte de franjas es grande, podría estar, por ejemplo, leyendo archivos en paralelo, haciendo referencia al throughput operations; en cambio si nuestra unidad de corte es chica, probablemente no podamos leer en simultáneo porque vamos a tener nuestro archivo dividido en muchas partecitas en los distintos discos, pero vamos a poder lograr reducir el tiempo de respuesta para los accesos en caso de archivos grandes (transfer rate).
RAID 0
RAID 0 optimiza el transfer rate de las operaciones pero es más propenso a fallas por no proveer redundancia.
RAID 1
RAID 1 tiene redundancia, pero todavía no implementa el tema de las franjas que si implementa RAID 0. RAID 1 es caro pero tiene muchas ventajas en relación a la tolerancia de fallas. Por otro lado, RAID 1 está limitado por lo que en realidad 1 disco puede almacenar, si nosotros hacemos raid de n discos de 1TB, igual tenemos 1TB de almacenamiento, simplemente tenemos n copias, el espacio de almacenamiento no aumenta.
RAID 2
Lo que tratamos de hacer con RAID 2 es no tener que copiar exactamente los datos, que mi redundancia no sea el mismo tamaño que tengo de datos, pero se queda a la mitad porque requiere de bastantes discos de redundancia para reconstruir la información perdida.
RAID 3
RAID 3 cambia lo que en RAID 2 molestaba, tener más de un disco de redundancia.
Para calcular la redundancia, RAID 3 va a utilizar la paridad, la cual significa que para cada nivel de franja vamos a tener un bit de paridad. Para que se entienda mejor, supongamos que en el 1er nivel de franja, tenemos a la franja del disk 1 con el primer bit igual a 0, a la franja del disk 2 con el primer bit igual a 1, y a la franja del disk 3 con el primer bit igual a 1, bueno, ahí vamos a tener ver si nuestro disco de redundancia tiene paridad par o impar
-> Si la paridad es par, al tener 0 - 1 - 1 respectivamente, vamos a tener que colocar como bit primero el 0, porque ya tenemos 2 bits pares, quedando 0 - 1 - 1 - 0
->Si la paridad es impar, se pondrá como primer bit el 1, quedando 0 - 1 - 1 - 1
La redundancia es la tolerancia a fallas. La idea de todo esto es que si por ejemplo se nos cae el disk 2, y nosotros queremos acceder al 1er nivel de franja del respectivo disk, a pesar de no tenerlo lo podemos calcular, ¿cómo?, si nosotros pusimos un 0 en el disk 1, un 1 en el disk 3, y un 0 en el disk de redundancia, sabiendo que nuestra paridad es par, podemos saber perfectamente que nuestro bit del disk 2 es un 1, por ser la paridad par.
Cada vez que se escriba en alguna franja de algunos de los 3 discos, también se deberá escribir en la respectiva franja de paridad del disco de redundancia, dicho acto en el caso de la imagen de arriba no molesta mucho ya que se encuentran sincronizados, pero veremos en RAID 4 que eso ya empieza a molestar.
RAID 4
RAID 4 toma las franjas más grandes para poder optimizar la cantidad de operaciones que hago, ya que como vimos anteriormente los cabezales tienen que ser independientes para poder hacer acciones como leer archivos en paralelo, entre otras. El problema en RAID 4 es cuando empiezan a haber bastantes escrituras, ya que si entre los distintos discos estoy escribiendo en distintas franjas, todas esas escrituras también se van a tener que escribir en el disco de paridad, generando cuello de botella, ya que se van a encolar todas las escrituras.
RAID 5
RAID 5 va a solucionar el problema de escrituras concurrentes de RAID 4, dividiendo en disco de paridad entre las distintas franjas de los otros discos.
RAID 6
RAID 6 es lo mismo que RAID 5 con la diferencia de que en vez de tener un solo disco de paridad (distribuido, pero al fin y al cabo es un solo disco), va a tener 2, calculando así en uno un tipo de paridad y en otro otro tipo de paridad, dando la posibilidad a que si se llegan a caer 2 discos, todavía podamos recuperar la información, cosa que no pasaba antes ya que solo podíamos recuperar la información de solo 1. En el gráfico “p” es una paridad y “q” es otra, distintos cálculos que se hacen para obtener dos redundancias distintas.